home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
cap
/
ogl_shapes.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
9KB
|
362 lines
/*
* Copyright (C) 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "ogl_shapes.h"
#define TORUSWIRE 0
#define TORUSSOLID 1
#define CUBEWIRE 2
#define CUBESOLID 3
#define NUM_LISTS 4
#define STACKDEPTH 10
#define ADD_QUAD 1
#define PI 3.1415926535897
typedef struct {
float mat[4][4];
float norm[3][3];
} mat_t;
static mat_t matstack[STACKDEPTH] = {
{{
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}
},
{
{1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{0.0, 0.0, 1.0}
}
}
};
static long identitymat = 1;
static long mattop = 0;
static GLuint lists[NUM_LISTS] = { 0, 0, 0, 0 };
static GLvoid
normalize(GLfloat v[3])
{
float d;
d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
if (d == 0.0) {
fprintf(stderr, "normalize: zero length vector\n");
v[0] = d = 1.0;
}
d = 1/d;
v[0] *= d;
v[1] *= d;
v[2] *= d;
}
static void
m_xformpt(GLfloat pin[3], GLfloat pout[3],
GLfloat nin[3], GLfloat nout[3])
{
long i;
float ptemp[3], ntemp[3];
mat_t *m = &matstack[mattop];
if (identitymat) {
for (i = 0; i < 3; i++) {
pout[i] = pin[i];
nout[i] = nin[i];
}
return;
}
for (i = 0; i < 3; i++) {
ptemp[i] = pin[0]*m->mat[0][i] +
pin[1]*m->mat[1][i] +
pin[2]*m->mat[2][i] +
m->mat[3][i];
ntemp[i] = nin[0]*m->norm[0][i] +
nin[1]*m->norm[1][i] +
nin[2]*m->norm[2][i];
}
for (i = 0; i < 3; i++) {
pout[i] = ptemp[i];
nout[i] = ntemp[i];
}
normalize(nout);
}
static GLvoid
doughnut(GLfloat r, GLfloat R, long nsides, long rings,
GLvoid (*savefunc)())
{
long i, j;
float theta, phi, theta1, phi1;
float p0[03], p1[3], p2[3], p3[3];
float n0[3], n1[3], n2[3], n3[3];
float t0[2], t1[2], t2[2], t3[2];
for (i = 0; i < rings; i++) {
theta = (float)i*2.0*PI/rings;
theta1 = (float)(i+1)*2.0*PI/rings;
for (j = 0; j < nsides; j++) {
phi = (float)j*2.0*PI/nsides;
phi1 = (float)(j+1)*2.0*PI/nsides;
t0[0] = ((float)i)/((float)rings);
t0[1] = ((float)j)/((float)nsides);
t1[0] = ((float)i+1)/((float)rings);
t1[1] = ((float)j)/((float)nsides);
t2[0] = ((float)i+1)/((float)rings);
t2[1] = ((float)j+1)/((float)nsides);
t3[0] = ((float)i)/((float)rings);
t3[1] = ((float)j+1)/((float)nsides);
p0[0] = cos(theta)*(R + r*cos(phi));
p0[1] = -sin(theta)*(R + r*cos(phi));
p0[2] = r*sin(phi);
p1[0] = cos(theta1)*(R + r*cos(phi));
p1[1] = -sin(theta1)*(R + r*cos(phi));
p1[2] = r*sin(phi);
p2[0] = cos(theta1)*(R + r*cos(phi1));
p2[1] = -sin(theta1)*(R + r*cos(phi1));
p2[2] = r*sin(phi1);
p3[0] = cos(theta)*(R + r*cos(phi1));
p3[1] = -sin(theta)*(R + r*cos(phi1));
p3[2] = r*sin(phi1);
n0[0] = cos(theta)*(cos(phi));
n0[1] = -sin(theta)*(cos(phi));
n0[2] = sin(phi);
n1[0] = cos(theta1)*(cos(phi));
n1[1] = -sin(theta1)*(cos(phi));
n1[2] = sin(phi);
n2[0] = cos(theta1)*(cos(phi1));
n2[1] = -sin(theta1)*(cos(phi1));
n2[2] = sin(phi1);
n3[0] = cos(theta)*(cos(phi1));
n3[1] = -sin(theta)*(cos(phi1));
n3[2] = sin(phi1);
m_xformpt(p0, p0, n0, n0);
m_xformpt(p1, p1, n1, n1);
m_xformpt(p2, p2, n2, n2);
m_xformpt(p3, p3, n3, n3);
(*savefunc)(ADD_QUAD, n3, t3, p3, n2, t2, p2, n1, t1, p1, n0, t0, p0);
}
}
}
static void
drawbox(float x0, float x1, float y0, float y1,
float z0, float z1, void (*savefunc)())
{
long i;
float temp;
float p0[3], p1[3], p2[3], p3[3];
float n0[3], n1[3], n2[3], n3[3];
float t0[2], t1[2], t2[2], t3[2];
float cv[8][3];
float cnorms[6][3] = {
{-1.0, 0.0, 0.0},
{0.0, 1.0, 0.0},
{1.0, 0.0, 0.0},
{0.0, -1.0, 0.0},
{0.0, 0.0, 1.0},
{0.0, 0.0, -1.0}
};
long faces[6][4] = {
{ 0, 1, 2, 3 },
{ 3, 2, 6, 7 },
{ 7, 6, 5, 4 },
{ 4, 5, 1, 0 },
{ 5, 6, 2, 1 },
{ 7, 4, 0, 3 }
};
if (x0 > x1) {
temp = x0;
x0 = x1;
x1 = temp;
}
if (y0 > y1) {
temp = y0;
y0 = y1;
y1 = temp;
}
if (z0 > z1) {
temp = z0;
z0 = z1;
z1 = temp;
}
cv[0][0] = cv[1][0] = cv[2][0] = cv[3][0] = x0;
cv[4][0] = cv[5][0] = cv[6][0] = cv[7][0] = x1;
cv[0][1] = cv[1][1] = cv[4][1] = cv[5][1] = y0;
cv[2][1] = cv[3][1] = cv[6][1] = cv[7][1] = y1;
cv[0][2] = cv[3][2] = cv[4][2] = cv[7][2] = z0;
cv[1][2] = cv[2][2] = cv[5][2] = cv[6][2] = z1;
t0[0] = 0.0;
t0[1] = 0.0;
t1[0] = 0.0;
t1[1] = 1.0;
t2[0] = 1.0;
t2[1] = 1.0;
t3[0] = 1.0;
t3[1] = 0.0;
for (i = 0; i < 6; i++) {
m_xformpt(&cv[faces[i][0]][0], p0, &cnorms[i][0], n0);
m_xformpt(&cv[faces[i][1]][0], p1, &cnorms[i][0], n1);
m_xformpt(&cv[faces[i][2]][0], p2, &cnorms[i][0], n2);
m_xformpt(&cv[faces[i][3]][0], p3, &cnorms[i][0], n3);
(*savefunc)(ADD_QUAD, n0, t0, p0, n1, t1, p1, n2, t2, p2, n3, t3, p3);
}
}
static GLvoid
savequad(long type,
GLfloat * n0, GLfloat * t0, GLfloat * v0,
GLfloat * n1, GLfloat * t1, GLfloat * v1,
GLfloat * n2, GLfloat * t2, GLfloat * v2,
GLfloat * n3, GLfloat * t3, GLfloat * v3)
{
glBegin (GL_POLYGON);
glNormal3fv(n0);
glVertex3fv(v0);
glNormal3fv(n1);
glVertex3fv(v1);
glNormal3fv(n2);
glVertex3fv(v2);
glNormal3fv(n3);
glVertex3fv(v3);
glEnd();
}
static GLvoid
savewirequad(long type,
GLfloat * n0, GLfloat * t0, GLfloat * v0,
GLfloat * n1, GLfloat * t1, GLfloat * v1,
GLfloat * n2, GLfloat * t2, GLfloat * v2,
GLfloat * n3, GLfloat * t3, GLfloat * v3)
{
glBegin (GL_LINE_LOOP);
glNormal3fv(n0);
glVertex3fv(v0);
glNormal3fv(n1);
glVertex3fv(v1);
glNormal3fv(n2);
glVertex3fv(v2);
glNormal3fv(n3);
glVertex3fv(v3);
glEnd();
}
/* Create display lists for rendering torii. */
static GLvoid
wireTorus (GLvoid)
{
lists[TORUSWIRE] = glGenLists (1);
glNewList(lists[TORUSWIRE], GL_COMPILE);
doughnut(0.25, 0.75, 5, 10, savewirequad);
glEndList();
}
static GLvoid
solidTorus (GLvoid)
{
lists[TORUSSOLID] = glGenLists (1);
glNewList(lists[TORUSSOLID], GL_COMPILE);
doughnut(0.25, 0.75, 8, 15, savequad);
glEndList();
}
static GLvoid
wireCube (GLvoid)
{
lists[CUBEWIRE] = glGenLists (1);
glNewList(lists[CUBEWIRE], GL_COMPILE);
drawbox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, savewirequad);
glEndList();
}
static GLvoid
solidCube (GLvoid)
{
lists[CUBESOLID] = glGenLists (1);
glNewList(lists[CUBESOLID], GL_COMPILE);
drawbox(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, savequad);
glEndList();
}
/* Render the appropriate display lists for the torii. */
GLvoid
doWireTorus (void)
{
if (glIsList(lists[TORUSWIRE]) == 0)
wireTorus ();
glCallList(lists[TORUSWIRE]);
}
GLvoid
doSolidTorus (void)
{
if (glIsList(lists[TORUSSOLID]) == 0)
solidTorus ();
glCallList(lists[TORUSSOLID]);
}
GLvoid
doWireCube (void)
{
if (glIsList(lists[CUBEWIRE]) == 0)
wireCube ();
glCallList(lists[CUBEWIRE]);
}
GLvoid
doSolidCube (void)
{
if (glIsList(lists[CUBESOLID]) == 0)
solidCube ();
glCallList(lists[CUBESOLID]);
}
GLvoid
initStockShapes (GLvoid)
{
wireTorus();
solidTorus();
wireCube();
solidCube();
}